TODO
----

* Commands for changing z order and focus.

* Think about protocol version management

* Try to assure that messages aren't repeated or are sent for hidden windows.

Overview
========

The protocol is a line based protocol following this simple syntax:

	OPERATION,SERIAL[,ARG1[,ARG2,[...]]]

Each operation will have an increasing serial number. The initial value is
implementation defined.

The goal is to have a generic protocol that can be used for other display
systems (e.g. VNC) as well.

One line may not exceed 1024 bytes, including newline.

The protocol has no concept of hidden or unmapped windows. A window does not
exist unless it is visible. Note that a minimized window is an exception to
this rule.

The protocol has no way of indicating failure, meaning that all commands are
expected to succeed. If a command fails, the receiving end must send a
corresponding command back, indicating the actual state.

Data types
==========
Window ID are written in hex, like 0x4321. 

Window positions can be negative. This happens when a window is moved
outside the desktop.

All integers fit inside 32 bits.

Strings are sent in UTF-8 and do not contain any characters less than 0x20 or
the character , (comma).

Server to Client Operations
===========================

CREATE
------

Allocate structures for a new window.

Syntax:
	CREATE,<SERIAL>,<ID>,<GRPID>,<PARENT>,<FLAGS>

Indicates that a window has appeared on the server. If PARENT is non-zero then
the new window is a child of that window (it's transient for it). The special
value 0xFFFFFFFF for PARENT means that the window is a popup window without a
parent. It's commonly used for splash screens, tool tips and context menus.

The group id identifies a set of windows that belong together. It is currently
only used for modal windows and DESTROYGRP.

Flags:
	0x0001 : Create a window that's modal with regard to the other windows
	         in the same group.

Note that very little information is included in this message. Things like
title and state will come in subsequent messages. This message should only
be used to allocate data structures for the new window.

DESTROY
-------

Remove a window.

Syntax:
	DESTROY,<SERIAL>,<ID>,<FLAGS>

Remove the window and deallocate all associated structures.

DESTROYGRP
----------

Destroy an entire group of windows.

Syntax:
	DESTROYGRP,<SERIAL>,<GRPID>,<FLAGS>

Every window that belongs to the group GRPID should be destroyed as if they
each got a DESTROY message.

POSITION
--------

Move and/or resize a window.

Syntax:
	POSITION,<SERIAL>,<ID>,<X>,<Y>,<WIDTH>,<HEIGHT>,<FLAGS>

If the window isn't visible yet (because a
STATE hasn't been set or because it's minimized), you must store the position
and size. A new POSITION is not guaranteed to be sent when the window changes
state.

TITLE
-----

Sets a window title.

Syntax:
	TITLE,<SERIAL>,<ID>,<TITLE>,<FLAGS>

The text is guaranteed to be stripped of control characters (< 0x20).

Note that this has the same requirement as POSITION, that the title needs to
be stored for newly created windows until a STATE is sent. It is however not
guaranteed that a TITLE will be sent before the first STATE.


ZCHANGE
-------

The window moved in z order.

Syntax:
	ZCHANGE,<SERIAL>,<ID>,<BEHIND>,<FLAGS>

The window with the id ID is behind the window with the id BEHIND. If
BEHIND is 0, then this window should be brought to the front. The ID
window is the window to be moved, while the BEHIND window is only used
as a reference.


STATE
-----

Changes the window's state and/or title.

Syntax:
	STATE,<SERIAL>,<ID>,<STATE>,<FLAGS>

State can have one of three values:
 0 : "Normal" window.
 1 : Minimized.
 2 : Maximized.

The initial STATE for a window will always be preceeded by one CREATE and one
POSITION. Optionally, a TITLE may also be sent before the first STATE.

DEBUG
-----

Debug output from the server component.

Syntax:
	DEBUG,<SERIAL>,<STRING>

Used for debugging.

SYNCBEGIN
---------

Indicates that a synchronisation has begun.

Syntax:
	SYNCBEGIN,<SERIAL>,<FLAGS>

Sent when the server starts a synchronisation. The client should flush all
information at this point.

SYNCEND
-------

Indicates that a synchronisation is complete.

Syntac:
	SYNCEND,<SERIAL>,<FLAGS>

Sent when the last message that is part of the synchronisation has been sent.
This may be followed by duplicate messages and/or messages referring invalid
windows that were queued up during the synchronisation.

HELLO
-----

Initial message sent by server.

Syntax:
	HELLO,<SERIAL>,<FLAGS>

The server starts each connection by sending this message. Normally the client
will react by sending a SYNC back to the server. 

Flags:
  0x0001 : This is a reconnect to an existing session.
  0x0002 : The desktop is currently hidden (see HIDE).

ACK
---

Acknowledgement of a request to manipulate a window.

Syntax:
	ACK,<SERIAL>,<ACKSERIAL>

Whenever one of the commands POSITION, ZCHANGE, STATE or FOCUS is executed on
the server, the server will send an ACK back to the client. The purpose of this
is to inform the client of when the operation was actually performed, allowing
high latencies in the channel.

HIDE
----

The desktop has become hidden on the server.

Syntax:
	HIDE,<SERIAL>,<FLAGS>

This message is sent when the desktop on the server is obscured by something
that cannot be tracked. The client should remove all windows and display the
entire desktop, allowing the user to handle whatever is blocking the view.

Note that updates to windows will still be sent as the windows still exist on
the server, they are merely not visible.

UNHIDE
------

The desktop has been restored on the server.

Syntax:
	UNHIDE,<SERIAL>,<FLAGS>

This message is sent some time after a HIDE, indicating that the windowed view
has been restored. If the client has dropped all information about windows then
it can send a SYNC to re-enumerate them.

SETICON
-------

Sets an icon for a window.

Syntax:
	SETICON,<SERIAL>,<ID>,<CHUNK>,<FORMAT>,<WIDTH>,<HEIGHT>,<DATA>

This message is sent when a window is initially created and at any time when
the application modifies its icon.

A window can have multiple icons, but only one of a given format and size. A
SETICON received for an already existing format and size is expected to over-
write that icon.

Since icons can potentially be very large, it can easily overflow the line
limitation in the protocol. To handle this, multiple SETICON will be issued
with an ever increasing chunk number.

The initial chunk is 0 (zero) and all chunks must be sent in order. Multiple
SETICON sets for the same window may not interleave. SETICON sets for
different windows may interleave though.

Formats:
  RGBA : Four bytes of data per pixel, representing red, green, blue and
         alpha, in that order.

Data is the raw icon data written in hex (e.g. 3fab32...). Chunks must be
divided on a whole byte boundary. Case is not specified.

DELICON
-------

Removes an icon for a window.

Syntax:
	DELICON,<SERIAL>,<ID>,<FORMAT>,<WIDTH>,<HEIGHT>

Removes the icon of a window matching the given format and size, previously
set with SETICON.

This command may not be interleaved with a SETICON set.

Client to Server Operations
===========================

SYNC
----

Request a synchronisation of window information.

Syntax:
	SYNC,<SERIAL>,<FLAGS>

For each window, the server will send CREATE, POSITION and STATE, in that
order, just as if the window was created. Note that a TITLE may also,
optionally, be sent before the STATE.

PERSISTENT
----------

Change persistent mode for the session.

Syntax:
	PERSISTENT,<SERIAL>,<ENABLE>

A seamless session always starts in persistent mode. This means that
the session will not terminate if all applications is closed. 
Upon re-connection to a session, the session will reset to persistent
mode and client needs to change this if non persistent mode is wanted.
If a persistent session not have any application running and is in
disconnected state, it will terminate after a timeout is reached that
matches the lifetime of the re-connection cookie.

POSITION
--------

Identical to the command sent from server to client.

TITLE
-----

Identical to the command sent from server to client.

ZCHANGE
-------

Identical to the command sent from server to client.

STATE
-----

Identical to the command sent from server to client.

FOCUS
-----

Sets which window has input focus.

Syntax:
	FOCUS,<SERIAL>,<ID>,<FLAGS>

Changes which window that will recieve the keyboard events. Note that this
might cause the window to change z order.

DESTROY
-------

Identical to the command sent from server to client.

SPAWN
-------

Spawn a new application.

Syntax:
	SPAWN,<SERIAL>,<COMMANDLINE>

Spawns a new application specified by commandline.


Test Cases
==========

A list of test cases is found below. These should be verified before
commit, ideally with different window managers (KWin, Metacity,
Blackbox, IceWM etc). You can also test without a window manager. 

1  Start Wordpad. Verify taskbar icon. 
 
2  Resize Wordpad main window. 
 
3  Open "Open Dialog". Resize, bigger than main window. Verify no
   additional task bar icons. Verify that the Open dialog is focused.
 
4  Open File Format box dropdown. Verify that it correctly appears
   outside main window. Verify no additional task bar icons. 
 
5  Abort Open. Select About Wordpad. Verify no additional task bar
   icons. Verify that the About dialog is focused. 
 
6  Minimize and restore Wordpad using the WM. Verify that both the
   Wordpad and About window is minimized and restored, and that the
   About window ends up in front of Wordpad. This test is known to fail
   with some WMs. Close the About dialog. 
 
7  Open Wordpad Help. Verify task bar icon. 
 
8  Switch between Help and Wordpad window using a X11 taskbar. 
 
9  In Wordpad, right click at the bottom of the document, and verify
   that the menu correctly appears outside the main window. Verify no
   additional task bar icons.
 
10 Click on the New icon. Select Text Document. Verify that the taskbar
   icon is updated.
 
11 Write something. Try the Find dialog (Ctrl-F). Move it outside the
   main window. Verify no task bar icons. 
 
12 Make Wordpad very small and try to use the menus. 
 
 
13 Start Internet Explorer. 
 
14 Minimize IE using the IE button. Restore. 
 
15 Minimize IE using the taskbar. Restore. 
 
16 Maximize IE using the IE button. Restore. 
 
17 Maximize IE using the taskbar. Restore. 
 
18 Open an additional IE window and verify you can switch between them. 
 
 
19 Try the menus in Microsoft Office XP, which uses shaded menus. 
 
 
20 Test transient windows: Run a program (ie Excel) seamlessly and open
   a modal dialog (ie Open). Move the dialog so it partially overlaps
   its parent window. Cover both windows with a third (ie a maximized
   xterm). Click on Excel's taskbar entry to bring it to the front.
 
 
21 Test topmost windows: Run Task Manager seamlessly
   (...\seamlessrdpshell.exe taskmgr). From Task Manager's File menu,
   select 'New Task (Run)' and run Notepad. Move Notepad so it
   partially overlaps Task Manager. Cover both windows with a native
   window (ie a maximized xterm). Click on Notepad's taskbar entry to
   bring it to the front.
 
 
22 Test X11 window close: Start Notepad and open the Help
   Browser. Close the Help Browser window on the X11 side using your
   window manager. Verify that rdesktop still runs and that the Notepad
   application window still exists.
 
 
23 Test window restacking: Run Mozilla Seamonkey and open two separate
   windows. From the first one, select the other one from the windows
   menu. Verify that the other window is brought to the front. Test
   this using both the mouse and the keyboard.
 
 
24 Test restacking of a bottom window. For this test, you'll need to
   the tool "notepadbehindwordpad.exe". Run Task Manager
   seamlessly. Start Notepad and Wordpad from it. Manually stack the
   windows as (from top to bottom) Task Manager - Notepad - xterm -
   Wordpad. Make sure the windows partially overlaps. From Task
   Manager, execute notepadbehindwordpad.exe. This
   test is expected to fail when rdesktop emits the warning about
   broken WM at startup.
 
 
25 Test restacking of a middle window. For this test, you'll need to
   the tool "notepadbehindwordpad.exe". Run Task Manager
   seamlessly. Start Paint, Notepad, and Wordpad from it. Manually
   stack the windows as (from top to bottom) Task Manager - Notepad -
   xterm - Wordpad - Paint. Make sure the windows partially
   overlaps. From Task Manager, execute notepadbehindwordpad.exe. This
   test is expected to fail when rdesktop emits the warning about
   broken WM at startup.


26 If running on a 64 bit Windows version, try a 32 bit application:
   Run Task Manager seamlessly (...\seamlessrdpshell.exe
   taskmgr). From Task Manager's File menu, select 'New Task (Run)'
   and run %windir%\syswow64\notepad.exe. Try various window
   operations.
